package com.raytoo.config.web;

import java.util.Properties;

import org.springframework.aop.Advisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextListener;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.support.spring.stat.BeanTypeAutoProxyCreator;
import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import com.raytoo.core.listener.ConfigListener;
import com.raytoo.core.xss.XssFilter;

/**
 * web 配置类
 *
 * @author fengshuonan
 * @date 2016年11月12日 下午5:03:32
 */
@Configuration
public class WebConfig {

    /**
     * druidServlet注册
     */
    @Bean
    public ServletRegistrationBean druidServletRegistration() {
        ServletRegistrationBean registration = new ServletRegistrationBean(new StatViewServlet());
        registration.addUrlMappings("/druid/*");
        return registration;
    }

    /**
     * druid监控 配置URI拦截策略
     * @return
     */
    @Bean
    public FilterRegistrationBean druidStatFilter(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        //添加过滤规则.
        filterRegistrationBean.addUrlPatterns("/*");
        //添加不需要忽略的格式信息.
        filterRegistrationBean.addInitParameter(
                "exclusions","/static/*,*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid,/druid/*");
        //用于session监控页面的用户名显示 需要登录后主动将username注入到session里
        filterRegistrationBean.addInitParameter("principalSessionName","username");
        return filterRegistrationBean;
    }

    /**
     * druid数据库连接池监控
     */
    @Bean
    public DruidStatInterceptor druidStatInterceptor() {
        return new DruidStatInterceptor();
    }


    @Bean
    public JdkRegexpMethodPointcut druidStatPointcut(){
        JdkRegexpMethodPointcut druidStatPointcut = new JdkRegexpMethodPointcut();
        String patterns = "com.raytoo.module.*.service.*";
        //可以set多个
        druidStatPointcut.setPatterns(patterns);
        return druidStatPointcut;
    }

    /**
     * druid数据库连接池监控
     */
    @Bean
    public BeanTypeAutoProxyCreator beanTypeAutoProxyCreator() {
        BeanTypeAutoProxyCreator beanTypeAutoProxyCreator = new BeanTypeAutoProxyCreator();
        beanTypeAutoProxyCreator.setTargetBeanType(DruidDataSource.class);
        beanTypeAutoProxyCreator.setInterceptorNames("druidStatInterceptor");
        return beanTypeAutoProxyCreator;
    }

    /**
     * druid 为druidStatPointcut添加拦截
     * @return
     */
    @Bean
    public Advisor druidStatAdvisor() {
        return new DefaultPointcutAdvisor(druidStatPointcut(), druidStatInterceptor());
    }

    /**
     * xssFilter注册
     */
    @Bean
    public FilterRegistrationBean xssFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean(new XssFilter());
        registration.addUrlPatterns("/*");
        return registration;
    }

    /**
     * RequestContextListener注册
     */
    @Bean
    public ServletListenerRegistrationBean<RequestContextListener> requestContextListenerRegistration() {
        return new ServletListenerRegistrationBean<>(new RequestContextListener());
    }

    /**
     * ConfigListener注册
     */
    @Bean
    public ServletListenerRegistrationBean<ConfigListener> configListenerRegistration() {
        return new ServletListenerRegistrationBean<>(new ConfigListener());
    }

    /**
     * 验证码生成相关
     */
    @Bean
    public DefaultKaptcha kaptcha() {
        Properties properties = new Properties();
//        properties.put("kaptcha.border", "no");
//        properties.put("kaptcha.border.color", "105,179,90");
//        properties.put("kaptcha.textproducer.font.color", "blue");
//        properties.put("kaptcha.image.width", "125");
//        properties.put("kaptcha.image.height", "45");
//        properties.put("kaptcha.textproducer.font.size", "45");
//        properties.put("kaptcha.session.key", "code");
//        properties.put("kaptcha.textproducer.char.length", "4");
//        properties.put("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
        
        /**  验证码边界，合法值yes or no  */
        properties.put("kaptcha.border", "no");
        /**   边界颜色，合法值 r,g,b (and optional alpha) or white,black,blue */
        properties.put("kaptcha.border.color", "black");
        /**   边界厚度,合法值 大于0 */
        properties.put("kaptcha.border.thickness", "1");
        /**   验证码图片宽度  */
        properties.put("kaptcha.image.width", "125");
        /**  验证码图片高度 */
        properties.put("kaptcha.image.height", "45");
        /**  验证码图片生成类，默认由DefaultKaptcha类生成，可以自己写一个图片生成类，需要实现Producer接口并继承Configurable类  */
        properties.put("kaptcha.producer.impl", "com.google.code.kaptcha.impl.DefaultKaptcha");
        /**  验证码生成类，默认由DefaultTextCreator类生成，可以自己写一个验证码生成类，需要实现TextProducer接口并继承Configurable类 */
        properties.put("kaptcha.textproducer.impl", "com.google.code.kaptcha.text.impl.DefaultTextCreator");
        /**  用来生成验证码的字符集 */
        properties.put("kaptcha.textproducer.char.string", "01234565789");
        /**  生成验证码的长度 */
        properties.put("kaptcha.textproducer.char.length", "4");
        /**  验证码字体，多个值用逗号隔开 */
        properties.put("kaptcha.textproducer.font.names", "Arial,Courier");
        /**  字体大小 */
        properties.put("kaptcha.textproducer.font.size", "40");
        /**  字体颜色 */
        properties.put("kaptcha.textproducer.font.color", "blue");
        /**  验证码字符间隔 */
        properties.put("kaptcha.textproducer.char.space", "5");
        /** 图片干扰生成类，默认由DefaultNoise类生成，可以自己写一个图片干扰类，需要实现NoiseProducer接口并继承Configurable类 */
        properties.put("kaptcha.noise.impl", "com.google.code.kaptcha.impl.DefaultNoise");
        /**  干扰颜色 */
        properties.put("kaptcha.noise.color", "yellow");
        /**  获取扭曲的不同风格的验证码，官方实现的有ShadowGimpy,FishEyeGimpy,WaterRipple,其中用来FishEyeGimpy之后上面设定的干扰线不起作用 */
        properties.put("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.FishEyeGimpy");
        /**  渐变背景色，初始颜色 */
        properties.put("kaptcha.background.clear.from", "gray");
        /**  渐变背景色，最终颜色 */
        properties.put("kaptcha.background.clear.to", "white");
        /**  文字渲染器 */
        properties.put("kaptcha.word.impl", "com.google.code.kaptcha.text.impl.DefaultWordRenderer");
//        properties.put("kaptcha.session.key", "KAPTCHA_SESSION_KEY");
//        properties.put("kaptcha.session.date", "KAPTCHA_SESSION_DATE");
        
        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
    
    
}
